var gamejs = require("gamejs");
var Radar = require("js/radar").Radar;
var Match = require("js/match").Match;
var Map = require("js/map").Map;
qModule("js/radar");

var currentMatch = new Match();
currentMatch.setMap(new Map(currentMatch, MAP_WIDTH, MAP_HEIGHT));
var testRadar = new Radar(currentMatch, [100, 200]);

test("test for Radar(match, coords)[constructor]", function() {
	deepEqual(testRadar.center, [100, 200], "ok for valid coordinates [100, 200]");
	
	throws(function() {
		testRadar = new Radar(currentMatch, [-5, 100]);
	}, RangeError, "ok for invalid coordinates [-5, 100][raise a RangeError]");
	
	throws(function() {
		testRadar = new Radar(currentMatch, [50, 0]);
	}, RangeError, "ok for invalid coordinates [50, 0] (image out of the map boundaries)[raise a RangeError]");
});

test("test for getMatch()", function() {
	strictEqual(testRadar.getMatch(), currentMatch, "ok for the correct object returned");
});

test("test for getBoundingRect()", function() {
	var center = [60, 60];
	testRadar = new Radar(currentMatch, center);
	var size = testRadar.image.getSize();
	var topLeft = [center[X] - size[WIDTH] / 2, center[Y] - size[HEIGHT] / 2];
	var expectedRect = new gamejs.Rect(topLeft, size);
	deepEqual(testRadar.getBoundingRect(), expectedRect, "ok for the correct rect returned");
});

test("test for getCenter()", function() {
	var center = [200, 300];
	testRadar = new Radar(currentMatch, center);
	strictEqual(testRadar.getCenter(), center,"ok for getCenter");
})

test("test for getRadius()", function() {
	testRadar = new Radar(currentMatch, [200, 300]);
	strictEqual(testRadar.getRadius(), testRadar.upgradeList[0].radius, "ok");
	
	testRadar.level = 1;
	strictEqual(testRadar.getRadius(), testRadar.upgradeList[1].radius, "ok, after an upgrade");
});

test("test for getAngularVelocity()", function() {
	testRadar = new Radar(currentMatch, [200, 300]);
	strictEqual(testRadar.getAngularVelocity(), testRadar.upgradeList[0].angularVelocity, "ok");
	
	testRadar.level = 1;
	strictEqual(testRadar.getAngularVelocity(), testRadar.upgradeList[1].angularVelocity, "ok, after an upgrade");
});

test("test for getLevel()", function() {
	testRadar = new Radar(currentMatch, [200, 300]);
	level = testRadar.level;
	strictEqual(testRadar.getLevel(), level, "ok");
	
	level = testRadar.level;
	currentMatch.credit = testRadar.priceToUpgrade();
	testRadar.upgrade();
	strictEqual(testRadar.getLevel(), level + 1,"ok after an upgrade");
});

test("test for priceToBuild()", function() {
	testRadar = new Radar(currentMatch, [200, 300]);
	strictEqual(testRadar.priceToBuild(), testRadar.upgradeList[0].price, "ok");
});

test("test for priceToUpgrade()", function() {
	testRadar = new Radar(currentMatch, [200, 300]);
	strictEqual(testRadar.priceToUpgrade(), testRadar.upgradeList[testRadar.getLevel() + 1].price, "ok from level = 0");
	
	if(testRadar.upgradeList.length > 2) {
		currentMatch.credit = testRadar.priceToUpgrade();
		testRadar.upgrade();
		strictEqual(testRadar.priceToUpgrade(), testRadar.upgradeList[testRadar.getLevel() + 1].price, "ok from level = 1");
	}
});

test("test for setStartAngle(angle)", function() {
	testRadar = new Radar(currentMatch, [200, 300]);
	testRadar.setStartAngle((3 / 2) * Math.PI);
	strictEqual(testRadar.startAngle, (3 / 2) * Math.PI, "ok for angle > 0");
	
	testRadar.setStartAngle(-(1 / 2) * Math.PI);
	strictEqual(testRadar.startAngle, -(1 / 2) * Math.PI, "ok for angle < 0");
	
	testRadar.setStartAngle(0);
	strictEqual(testRadar.startAngle, 0, "ok for angle = 0");
	
	throws(function() {
		testRadar.setStartAngle(NaN);
	}, RangeError, "ok for angle = Nan[raise a RangeError]");
	
	throws(function() {
		testRadar.setStartAngle(Infinity);
	}, RangeError, "ok for angle = Infinity[raise a RangeError]");
	
	throws(function() {
		testRadar.setStartAngle();
	}, TypeError, "ok for angle not defined[raise a TypeError]");
});

test("test for setCentralAngle(angle)", function() {
	testRadar = new Radar(currentMatch, [200, 300]);
	testRadar.setCentralAngle((3 / 2) * Math.PI);
	strictEqual(testRadar.centralAngle, (3 / 2) * Math.PI, "ok for PI/6 < angle < 2*PI");
	
	testRadar.setCentralAngle(2 * Math.PI);
	strictEqual(testRadar.centralAngle, 2 * Math.PI, "ok for angle = 2*PI");
	
	testRadar.setCentralAngle(Math.PI / 6);
	strictEqual(testRadar.centralAngle, Math.PI / 6, "ok for angle = PI/6");
	
	throws(function() {
		testRadar.setCentralAngle((7 / 2) * Math.PI);
	}, RangeError, "ok for angle > 2*PI[raise a RangeError]");
	
	throws(function() {
		testRadar.setCentralAngle((1 / 8) * Math.PI);
	}, RangeError, "ok for angle < PI/8[raise a RangeError]");
	
	throws(function() {
		testRadar.setCentralAngle(NaN);
	}, RangeError, "ok for angle = Nan[raise a RangeError]");
	
	throws(function() {
		testRadar.setCentralAngle(Infinity);
	}, RangeError, "ok for angle = Infinity[raise a RangeError]");
	
	throws(function() {
		testRadar.setCentralAngle();
	}, TypeError, "ok for angle not defined[raise a TypeError]");
});

test("test for getResaleValue()", function() {
        var testRadar = new Radar(currentMatch, [100, 200]);
        strictEqual(testRadar.getResaleValue(), 70, "resale value of the first level of upgrade");
        if(currentMatch.credit >= testRadar.priceToUpgrade()) {
                    testRadar.upgrade();
                    strictEqual(testRadar.getResaleValue(), 100, "resale value of the second level of upgrade");
        }
        else {
                    throws(function() {
		    testRadar.upgrade();
	            }, Error, "ok for not enough credit to upgrade");
        }

});

test("test for canUpgrade()", function() {
        var testRadar = new Radar(currentMatch, [100, 200]);
        for(i = 0;i< testRadar.upgradeList.length;i++) {                     // added a for cycle for a future implementation
          if(i == testRadar.upgradeList.length - 1) {                        // of more level in upgradeList
              ok(!testRadar.canUpgrade(), "the radar can't be upgraded");
          }
          else {
              ok(testRadar.canUpgrade(), "the radar can be upgraded");
              if(currentMatch.credit >= testRadar.priceToUpgrade()) {
                    testRadar.upgrade();
              }
              else {
                    throws(function() {
		    testRadar.upgrade();
	            }, Error, "ok for not enough credit to upgrade");
	            break;
              }

          }
        }
});

test("test for upgrade()", function() {
	testRadar = new Radar(currentMatch, [200, 300]);
	var cost = testRadar.upgradeList[1].price;
	currentMatch.credit = cost + 100;
	testRadar.upgrade();
	strictEqual(currentMatch.credit, 100, "ok for removing the credit");
	
	strictEqual(testRadar.level, 1, "ok for incrementing the level");
	
	testRadar.level = 0;
	currentMatch.credit = cost - 50;
	throws(function() {testRadar.upgrade();}, /InvalidOperationError/, "ok for upgrade with no credits[raise a InvalidOperationError]");
});

test("test for getObstructiveRadius()", function() {
	testRadar = new Radar(currentMatch, [200, 300]);
	var rect = testRadar.getBoundingRect();
	var expected = Math.round((rect.width > rect.height ? rect.width : rect.height) / 2);
	strictEqual(testRadar.getObstructiveRadius(), expected, "ok for removing the credit");
});

test("test for setSaleable()", function() {
	testRadar = new Radar(currentMatch, [200,300]);
	testRadar.setSaleable(false);
	ok(!(testRadar.saleable), "ok for setSaleable in normal situation");
	
	testRadar.setSaleable("true");
	//all non empty string evaluates to true
	ok(testRadar.saleable, "ok for string input");
});

test("test for sell()", function(){
	testRadar = new Radar(currentMatch, [200,300]);
	currentMatch.changeCredit(10000);
	currentMatch.getMap().addRadar(testRadar);
	testRadar.sell();
	var radarGroup = currentMatch.getMap().getRadars();
	ok( ! radarGroup.has(testRadar), "ok for removing correctly with sell");
});